package com.yc;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@Data
public class Person {
    String name;
    Address address;
    Person father;
    Person mather;
    List<Person> friends;

    public Person(String name) {
        this.name = name;
    }

    String say(String msg){
        return name + "说:" + msg;
    }

    static Person createZhangSan(){
        Person zhangsan = new Person("张三");
        zhangsan.father = new Person("张三丰");
        zhangsan.mather = new Person("李四");
        zhangsan.address = new Address("湖南","衡阳","工学院xxxx");
        zhangsan.friends = new ArrayList<>();
        zhangsan.friends.add(new Person("王五"));
        zhangsan.friends.add(new Person("赵六"));
        zhangsan.friends.add(new Person("刘七"));
        return zhangsan;
    }
    public static void test(){
        Person zhangSan = createZhangSan();
        System.out.println("getValue(zhangSan, \"name\") = " + getValue(zhangSan, "name"));
        System.out.println("getValue(zhangSan, \"mather.name\") = " + getValue(zhangSan, "mather.name"));
        System.out.println("getValue(zhangSan, \"father.name\") = " + getValue(zhangSan, "father.name"));
        System.out.println("getValue(zhangSan, \"address.city\") = " + getValue(zhangSan, "address.city"));
        // 扩展实现以下 2 个 ognl 语法
        System.out.println("getValue(zhangSan, \"friends[1].name\") = " + getValue(zhangSan, "friends[1].name"));
        System.out.println("getValue(zhangSan, \"#father.say('你好中国')\") = " + getValue(zhangSan, "#father.say('你好中国')"));
    }

    public static void main(String[] args) {
        test();
    }

    public static Object getValue(Object object, String path) {
        try {
            // 使用反射实现当前方法
            Class<?> aClass = object.getClass();
            Object value = null;
            if (path.contains(".")) {
                int index = path.indexOf(".");
                String prefix = path.substring(0,index);
                String suffix = path.substring(index+1);
                // 递归调用
                Object prefixValue = getValue(object, prefix);
                // 获取后面的值
                return getValue(prefixValue, suffix);
            } else {
                // 当前对象的属性
                Field field = aClass.getDeclaredField(path);
                // 建议通过属性方法获取属性值
                // name => getName
                String methodName = "get"
                        + field.getName().substring(0,1).toUpperCase()
                        + field.getName().substring(1);
                Method method = aClass.getMethod(methodName);
                value = method.invoke(object);
            }
            return value;
        } catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}
@Data
@AllArgsConstructor
class Address{
    String province;
    String city;
    String location;
}
